<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>个人博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:type" content="website">
<meta property="og:title" content="个人博客">
<meta property="og:url" content="http://codercheng.cn/page/3/index.html">
<meta property="og:site_name" content="个人博客">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="CoderCheng">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/atom.xml" title="个人博客" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.lug.ustc.edu.cn/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/css/style.css">

<meta name="generator" content="Hexo 4.2.1"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">个人博客</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="搜索"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://codercheng.cn"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main">
  
    <article id="post-RocketMQ介绍" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2021/03/01/RocketMQ%E4%BB%8B%E7%BB%8D/" class="article-date">
  <time datetime="2021-03-01T05:57:25.537Z" itemprop="datePublished">2021-03-01</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2021/03/01/RocketMQ%E4%BB%8B%E7%BB%8D/">RocketMQ介绍</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="categories-MQ"><a href="#categories-MQ" class="headerlink" title="categories: MQ"></a>categories: MQ</h2><p>​                                                  <strong>RockerMQ学习笔记</strong></p>
<h1 id="RocketMQ介绍"><a href="#RocketMQ介绍" class="headerlink" title="RocketMQ介绍"></a>RocketMQ介绍</h1><ul>
<li>rocketmq是阿里巴巴团队使用java语言开发的一款分布式消息中间件，是一款低延迟，高可用，拥有海量消息堆积能力和灵活拓展性的消息队列。</li>
</ul>
<h2 id="RocketMQ组成部分"><a href="#RocketMQ组成部分" class="headerlink" title="RocketMQ组成部分"></a>RocketMQ组成部分</h2><ul>
<li>rocketmq由四大核心模块组成：<strong>producer、consumer、brokerServer、nameServer</strong>。其中brokerServer和nameServer是rocketmq的服务端，两者一起独立的对外提供服务；而producer和consumer可看做是rocketmq的客户端，一般依附于业务应用程序</li>
</ul>
<h3 id="Producer"><a href="#Producer" class="headerlink" title="Producer"></a>Producer</h3><p><strong>producer负责发送消息</strong>。使用producer将消息发送到brokerServer，由brokerServer统一进行消息的分发。</p>
<p>　　rocketmq支持多种消息发送方式，如<strong>同步消息发送</strong>、<strong>异步回调消息发送</strong>、<strong>顺序消息发送</strong>以及<strong>单向消息发送(异步无回调)</strong>。除了单向消息发送，其余的发送方式均需要brokerServer返回发送结果的确认消息。</p>
<h3 id="Consumer"><a href="#Consumer" class="headerlink" title="Consumer"></a>Consumer</h3><p>​     <strong>consumer 负责消费producer发送的消息</strong>。consumer会从brokerServer获取消息，并传递给应用程序。</p>
<p>　　<strong>rocketMQ使用的消息原语是At Least Once(至少一次成功消费)，</strong>如果一定时间内没有接收到consumer消息确认消费的响应结果，会将同一条消息再次投递给consumer。rocketmq采用ack机制保证消息的消费成功<strong>，</strong>所以consumer可能会多次收到同一条消息，需要consumer的业务方做好幂等防护。</p>
<p>​          从使用者的角度来看，consumer分为两种方式来获取信息。一种是<strong>推模式(push consume)</strong>，推模式看起来像是brokerServer将消息推给了consumer；另一种是<strong>拉模式(pull consume)</strong>，拉模式看起来像是consumer主动的去brokerServer拉取消息(实际上，推模式是基于拉模式实现的)。</p>
<h3 id="BrokerServer"><a href="#BrokerServer" class="headerlink" title="BrokerServer"></a>BrokerServer</h3><p><strong>brokerServer负责消息的接收，存储和分发，</strong>是rocketmq最核心，最重量级的组成部分。</p>
<p>　　为实现高可用和高吞吐，brokerServer通常采用集群部署，共同对外提供服务。</p>
<h3 id="NameServer"><a href="#NameServer" class="headerlink" title="NameServer"></a>NameServer</h3><p>​           <strong>nameServer负责提供路由元数据</strong>。例如，brokerServer通常是集群部署的，其拓扑结构会经常的发生变化。如果每次集群中broker机器的上下线都需要通知所有的消费者、生产者，效率太低。</p>
<p>　　因此，rocketmq引入了nameServer作为brokerServer路由信息的维护者，broker的每次上下线都和nameServer通信，由nameServer来维护broker的路由信息，而producer和consumer通过访问nameServer获得对应broker的访问地址后，再向对应的broker发起请求。<strong>nameServer解除了broker和客户端的耦合依赖关系，大大提高了效率</strong></p>
<p> 在其它主流消息队列中也存在着类似的维护元信息功能的组件，如zookeeper等。rocketmq的设计者认为zk的功能过于强大，杀鸡焉用牛刀，通过一个精简版的元数据服务nameServer，以减少对外部系统的耦合依赖，得以提供更可靠的服务。</p>
<p>　　nameServer同样能以集群形式对外提供服务。但和zk集群不同的是，集群内的nameServer服务器并不会互相通信，而是保持相互独立。</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202103/01/140503-745030.png" alt="image-20210301135510557"></p>
<p>后台 启动 nameserver</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nohup mqnamesrv &amp;</span><br></pre></td></tr></table></figure>

<p>  后台 启动 broker</p>
   <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nohup mqbroker -n 117.50.7.7:9876 -c &#x2F;opt&#x2F;rocketmq&#x2F;conf&#x2F;broker.conf  &amp;</span><br></pre></td></tr></table></figure>






      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2021/03/01/RocketMQ%E4%BB%8B%E7%BB%8D/" data-id="cko3snvwt000hi8uo1qtj1a1j" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-博客迁移" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2021/02/25/%E5%8D%9A%E5%AE%A2%E8%BF%81%E7%A7%BB/" class="article-date">
  <time datetime="2021-02-25T03:42:25.613Z" itemprop="datePublished">2021-02-25</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2021/02/25/%E5%8D%9A%E5%AE%A2%E8%BF%81%E7%A7%BB/">博客迁移</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>​            博客迁移</p>
<p>3333333333333333333333</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2021/02/25/%E5%8D%9A%E5%AE%A2%E8%BF%81%E7%A7%BB/" data-id="cko3snvx9001ai8uo5rt4awjd" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-Kafka学习笔记" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2021/02/10/Kafka%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" class="article-date">
  <time datetime="2021-02-10T06:19:58.206Z" itemprop="datePublished">2021-02-10</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2021/02/10/Kafka%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">Kafka学习笔记</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="categories-MQ"><a href="#categories-MQ" class="headerlink" title="categories: MQ"></a>categories: MQ</h2><p>​                                                                          Kafka学习笔记</p>
<p>​        Kafka是最初由Linkedin公司开发，是一个分布式、分区的、多副本的、多生产者、多订阅者，基于zookeeper协调的分布式日志系统（也可以当做MQ系统），常见可以用于web/nginx日志、访问日志，消息服务等等，Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。</p>
<p>主要应用场景是：日志收集系统和消息系统。</p>
<p>Kafka主要设计目标如下：</p>
<p>以时间复杂度为O(1)的方式提供消息持久化能力，即使对TB级以上数据也能保证常数时间的访问性能。</p>
<p>高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条消息的传输。支持Kafka Server间的消息分区，及分布式消费，同时保证每个partition内的消息顺序传输。</p>
<p>同时支持离线数据处理和实时数据处理。支持在线水平扩展</p>
<p>有两种主要的消息传递模式：<strong>点对点传递模式、发布</strong>-<strong>订阅模式</strong>。大部分的消息系统选用发布-订阅</p>
<p>模式。Kafka<strong>就是一种发布</strong>-<strong>订阅模式</strong>。</p>
<p>Kafka只有消息的拉取，没有推送，可以通过轮询实现消息的推送。</p>
<ol>
<li><p>Kafka在一个或多个可以跨越多个数据中心的服务器上作为集群运行。</p>
</li>
<li><p>Kafka集群中按照主题分类管理，一个主题可以有多个分区，一个分区可以有多个副本分区。</p>
</li>
<li><p>每个记录由一个键，一个值和一个时间戳组成</p>
</li>
</ol>
<p>Kafka<strong>优势</strong></p>
<ol>
<li>高吞吐量：单机每秒处理几十上百万的消息量。即使存储了许多TB的消息，它也保持稳定的性</li>
</ol>
<p>能。</p>
<ol start="2">
<li><p>高性能：单节点支持上千个客户端，并保证零停机和零数据丢失。</p>
</li>
<li><p>持久化数据存储：将消息持久化到磁盘。通过将数据持久化到硬盘以及replication防止数据丢失。</p>
<ul>
<li>1  零拷贝 </li>
<li>2  顺序读，顺序写</li>
<li>3 利用Linux的页缓存</li>
</ul>
</li>
<li><p>分布式系统，易于向外扩展。所有的Producer、Broker和Consumer都会有多个，均为分布</p>
</li>
</ol>
<p>式的。无需停机即可扩展机器。多个Producer、Consumer可能是不同的应用。</p>
<ol start="5">
<li><p>可靠性 - Kafka是分布式，分区，复制和容错的。</p>
</li>
<li><p>客户端状态维护：消息被处理的状态是在Consumer端维护，而不是由server端维护。当失</p>
</li>
</ol>
<p>败时能自动平衡。</p>
<ol start="7">
<li><p>支持online和offline的场景。</p>
</li>
<li><p>支持多种客户端语言。Kafka支持Java、.NET、PHP、Python等多种语言。</p>
</li>
</ol>
<p><strong>核心概念</strong></p>
<p><strong>Producer</strong></p>
<p>生产者创建消息。</p>
<p>该角色将消息发布到Kafka的topic中。broker接收到生产者发送的消息后，broker将该消息<strong>追</strong> </p>
<p><strong>加</strong>到当前用于追加数据的 segment 文件中。</p>
<p>一般情况下，一个消息会被发布到一个特定的主题上。</p>
<ol>
<li><p>默认情况下通过轮询把消息均衡地分布到主题的所有分区上。</p>
</li>
<li><p>在某些情况下，生产者会把消息直接写到指定的分区。这通常是通过消息键和分区器来实现</p>
</li>
</ol>
<p>的，分区器为键生成一个散列值，并将其映射到指定的分区上。这样可以保证包含同一个键的</p>
<p>消息会被写到同一个分区上。</p>
<ol start="3">
<li>生产者也可以使用自定义的分区器，根据不同的业务规则将消息映射到分区。</li>
</ol>
<p><strong>Consumer</strong></p>
<p>消费者读取消息。</p>
<ol>
<li><p>消费者订阅一个或多个主题，并按照消息生成的顺序读取它们。</p>
</li>
<li><p>消费者通过检查消息的<strong>偏移量</strong>来区分已经读取过的消息。偏移量是另一种元数据，它是一个<strong>不断递增的整数值</strong>，在创建消息时，Kafka 会把它添加到消息里。在给定的<strong>分区</strong>里，每个消息的偏移量都是<strong>唯一</strong>的。消费者把每个分区最后读取的消息偏移量保存在Zookeeper 或Kafka上，如果消费者关闭或重启，它的读取状态不会丢失。</p>
</li>
<li><p>消费者是<strong>消费组</strong>的一部分。群组保证每个分区只能被一个消费者使用。</p>
</li>
<li><p>如果一个消费者失效，消费组里的其他消费者可以接管失效消费者的工作，再平衡，分区重新分配。</p>
</li>
</ol>
<p><strong>Broker</strong></p>
<p>一个独立的Kafka 服务器被称为broker。</p>
<p>broker 为消费者提供服务，对读取分区的请求作出响应，返回已经提交到磁盘上的消息。</p>
<ol>
<li><p>如果某topic有N个partition，集群有N个broker，那么每个broker存储该topic的一个partition。 </p>
</li>
<li><p>如果某topic有N个partition，集群有(N+M)个broker，那么其中有N个broker存储该topic的一个partition，剩下的M个broker不存储该topic的partition数据。</p>
</li>
<li><p>如果某topic有N个partition，集群中broker数目少于N个，那么一个broker存储该topic的一个或多个partition。在实际生产环境中，尽量避免这种情况的发生，这种情况容易导致Kafka集群数据不均衡。broker 是集群的组成部分。每个集群都有一个broker 同时充当了集群控制器的角色（自动从集群的活跃成员中选举出来）。</p>
</li>
</ol>
<p>在集群中，一个分区从属于一个broker，该broker 被称为分区的首领。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2021/02/10/Kafka%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" data-id="cko3snvwp000bi8uo26tk6i9t" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-RabbitMQ 学习笔记" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2021/01/26/RabbitMQ%20%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" class="article-date">
  <time datetime="2021-01-26T09:04:12.939Z" itemprop="datePublished">2021-01-26</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2021/01/26/RabbitMQ%20%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">RabbitMQ 学习笔记</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<p>categories: MQ<br>—                                       RabbitMQ 学习笔记</p>
<p>RPC主要基于TCP/UDP协议，HTTP协议是应用层协议，是构建在传输层协议TCP之上的，RPC效率更高，RPC长连接：不必每次通信都像HTTP一样三次握手，减少网络开销；</p>
<p>HTTP服务开发迭代更快：在接口不多，系统与系统之间交互比较少的情况下，HTTP就显得更加方便；相反，在接口比较多，系统与系统之间交互比较多的情况下，HTTP就没有RPC有优势。</p>
<p> <strong>分布式同步通信的问题</strong></p>
<p>电商项目中，如果后台添加商品信息，该信息放到数据库。我们同时，需要更新搜索引擎的倒排索引同时，假如有商品页面的静态化处理，也需要更新该页面信息</p>
<p>归根到底，是同步调用处理不当。这个问题在分布式架构中尤为严重。</p>
<p>消息中间件也可以称消息队列，是指用高效可靠的消息传递机制进行与平台无关的数据交流，并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息队列模型，可以在分布式环境下扩展进程的通信</p>
<p>消息中间件就是在通信的上下游之间截断：break it，Broker 然后利用中间件解耦、异步的特性，构建弹性、可靠、稳定的系统。</p>
<p><strong>异步处理</strong>、<strong>流量削峰</strong>、限流、缓冲、排队、<strong>最终一致性</strong>、<strong>消息驱动</strong>等需求的场景都可以使用消息中间件</p>
<p><strong>RabbitMQ</strong></p>
<p>RabbitMQ开始是用在电信业务的可靠通信的，也是少有的几款支持AMQP协议的产品之一。</p>
<p>优点：</p>
<ol>
<li><p>轻量级，快速，部署使用方便</p>
</li>
<li><p>支持灵活的路由配置。RabbitMQ中，在生产者和队列之间有一个交换器模块。根据配置的路</p>
</li>
</ol>
<p>由规则，生产者发送的消息可以发送到不同的队列中。路由规则很灵活，还可以自己实现。</p>
<ol start="3">
<li>RabbitMQ的客户端支持大多数的编程语言。</li>
</ol>
<p>缺点：</p>
<ol>
<li><p>如果有大量消息堆积在队列中，性能会急剧下降</p>
</li>
<li><p>RabbitMQ的性能在Kafka和RocketMQ中是最差的，每秒处理几万到几十万的消息。如果应</p>
</li>
</ol>
<p>用要求高的性能，不要选择RabbitMQ。 </p>
<ol start="3">
<li>RabbitMQ是Erlang开发的，功能扩展和二次开发代价很高。</li>
</ol>
<p><strong>RabbitMQ工作流程详解</strong></p>
<p> <strong>生产者发送消息的流程</strong></p>
<ol>
<li><p>生产者连接RabbitMQ，建立TCP连接( Connection)，开启信道（Channel） </p>
</li>
<li><p>生产者声明一个Exchange（交换器），并设置相关属性，比如交换器类型、是否持久化等</p>
</li>
<li><p>生产者声明一个队列井设置相关属性，比如是否排他、是否持久化、是否自动删除等</p>
</li>
<li><p>生产者通过 bindingKey （绑定Key）将交换器和队列绑定（ binding ）起来</p>
</li>
<li><p>生产者发送消息至RabbitMQ Broker，其中包含 routingKey （路由键）、交换器等信息</p>
</li>
<li><p>相应的交换器根据接收到的 routingKey 查找相匹配的队列。</p>
</li>
<li><p>如果找到，则将从生产者发送过来的消息存入相应的队列中。</p>
</li>
<li><p>如果没有找到，则根据生产者配置的属性选择丢弃还是回退给生产者</p>
</li>
<li><p>关闭信道。</p>
</li>
<li><p>关闭连接。</p>
</li>
</ol>
<p><strong>消费者接收消息的过程</strong></p>
<ol>
<li><p>消费者连接到RabbitMQ Broker ，建立一个连接(Connection ) ，开启一个信道(Channel) 。 </p>
</li>
<li><p>消费者向RabbitMQ Broker 请求消费相应队列中的消息，可能会设置相应的回调函数， 以及做一些准备工作</p>
</li>
<li><p>等待RabbitMQ Broker 回应并投递相应队列中的消息， 消费者接收消息。</p>
</li>
<li><p>消费者确认( ack) 接收到的消息。</p>
</li>
<li><p>RabbitMQ 从队列中删除相应己经被确认的消息。</p>
</li>
<li><p>关闭信道。</p>
</li>
<li><p>关闭连接。</p>
</li>
</ol>
<p>RabbitMQ TTL 机制    死信队列        延迟队列</p>
<p>RabbitMQ 可以<strong>对消息和队列两个维度来设置TTL</strong>。</p>
<p>任何消息中间件的容量和堆积能力都是有限的，如果有一些消息总是不被消费掉，那么需要有一种过期的机制来做兜底。</p>
<p>目前有两种方法可以设置消息的TTL。 </p>
<ol>
<li><p>通过Queue属性设置，队列中所有消息都有相同的过期时间。</p>
</li>
<li><p>对消息自身进行单独设置，每条消息的TTL 可以不同。</p>
</li>
</ol>
<p>如果两种方法一起使用，则消息的TTL 以两者之间<strong>较小数值为准</strong>。通常来讲，消息在队列中的生存时间一旦超过设置的TTL 值时，就会变成“死信”(Dead Message)，消费者默认就无法再收到该消息。当然，“死信”也是可以被取出来消费的</p>
<p>  一般 固定时长 用TTL+死信队列   比如 订单取消</p>
<p><strong>延迟消息</strong>是指的消息发送出去后并不想立即就被消费，而是需要等（指定的）一段时间后才触发消费。</p>
<p>可以使用<strong>rabbitmq_delayed_message_exchange</strong>插件实现。</p>
<p>这里和TTL方式有个很大的不同就是TTL存放消息在死信队列(delayqueue)里，二基于插件存放消息在延时交换机里(x-delayed-message exchange)。 </p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/26/171322-46544.png" alt="image-20210126171322013"></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2021/01/26/RabbitMQ%20%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" data-id="cko3snvws000fi8uo3y2ffpgk" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-redis常用命令" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2021/01/15/redis%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/" class="article-date">
  <time datetime="2021-01-15T05:34:59.844Z" itemprop="datePublished">2021-01-15</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2021/01/15/redis%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/">redis常用命令</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="categories-Redis"><a href="#categories-Redis" class="headerlink" title="categories: Redis"></a>categories: Redis</h2><p>​                                                    <strong>redis常用命令</strong></p>
<p>Redis简介</p>
<p>Redis是一个Key-Value的存储系统，使用ANSI C语言编写。</p>
<p>key的类型是字符串。</p>
<p>value的数据类型有：</p>
<p>常用的：string字符串类型、list列表类型、set集合类型、sortedset（zset）有序集合类型、hash类型。</p>
<p>不常见的：bitmap位图类型、geo地理位置类型。</p>
<p>Redis5.0新增一种：stream类型</p>
<p>注意：Redis中命令是忽略大小写，（set SET），key是不忽略大小写的 （NAME name）</p>
<p><strong>Redis的Key的设计</strong></p>
<ol>
<li><p>用:分割</p>
</li>
<li><p>把表名转换为key前缀, 比如: user:</p>
</li>
<li><p>第二段放置主键值</p>
</li>
<li><ol start="4">
<li>第三段放置列名</li>
</ol>
</li>
</ol>
<p>比如：用户表user, 转换为redis的key-value存储</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/120041-780160.png" alt="image-20210115120041410"></p>
<p> String 常用命令</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/120233-350827.png" alt="image-20210115120231936"></p>
<p> list  常用命令</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/120634-648466.png" alt="image-20210115120634665"></p>
<p>set 命令：</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/120730-706198.png" alt="image-20210115120729499"></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/120741-643672.png" alt="image-20210115120741576"></p>
<p>SortedSet(ZSet) 有序集合： 元素本身是无序不重复的</p>
<p>每个元素关联一个分数(score)</p>
<p>可按分数排序，分数可重复</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/120835-691890.png" alt="image-20210115120834530"></p>
<p>**hash类型（散列表）</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/120914-984249.png" alt="image-20210115120913754"></p>
<p>应用场景：</p>
<p>对象的存储 ，表数据的映射</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/120933-189593.png" alt="image-20210115120933218"></p>
<p><strong>bitmap位图类型</strong></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/121010-687561.png" alt="image-20210115121009723"></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/121021-843344.png" alt="image-20210115121020513"></p>
<p><strong>geo地理位置类型</strong></p>
<p>geo是Redis用来处理位置信息的。在Redis3.2中正式使用。主要是利用了Z阶曲线、Base32编码和</p>
<p>geohash算法</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/133244-775648.png" alt="image-20210115133242515"></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/133301-76001.png" alt="image-20210115133301114"></p>
<p><strong>stream数据流类型</strong></p>
<p>stream是Redis5.0后新增的数据结构，用于可持久化的消息队列。</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/133337-948273.png" alt="image-20210115133337748"></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/133354-217675.png" alt="image-20210115133353890"></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2021/01/15/redis%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/" data-id="cko3snvx80019i8uobhfiboxw" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-redis 集群（redis_cluster）搭建" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2021/01/14/redis%20%E9%9B%86%E7%BE%A4%EF%BC%88redis_cluster%EF%BC%89%E6%90%AD%E5%BB%BA/" class="article-date">
  <time datetime="2021-01-14T06:29:06.675Z" itemprop="datePublished">2021-01-14</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2021/01/14/redis%20%E9%9B%86%E7%BE%A4%EF%BC%88redis_cluster%EF%BC%89%E6%90%AD%E5%BB%BA/">redis 集群（redis_cluster）搭建</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="categories-Redis"><a href="#categories-Redis" class="headerlink" title="categories: Redis"></a>categories: Redis</h2><p>redis 集群（redis_cluster）搭建</p>
<p>RedisCluster最少需要三台主服务器，三台从服务器。 </p>
<ul>
<li>下载redis 对应的版本</li>
</ul>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget http://download.redis.io/releases/redis<span class="literal">-5</span>.<span class="number">0.5</span>.tar.gz</span><br></pre></td></tr></table></figure>

<ul>
<li><p>解压文件</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar <span class="literal">-xzf</span> redis<span class="literal">-5</span>.<span class="number">0.5</span>.tar.gz</span><br></pre></td></tr></table></figure>

<ul>
<li><p>新建redis_cluster 文件夹并 新建7001-7006 目录</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir redis_cluster</span><br><span class="line">cd  redis_cluster/ </span><br><span class="line">mkdir <span class="number">7001</span> <span class="number">7002</span> <span class="number">7003</span> <span class="number">7004</span> <span class="number">7005</span> <span class="number">7006</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>编译 redis </p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make install PREFIX=/root/redis_cluster/redis_cluster/<span class="number">7001</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>拷贝配置文件</p>
   <figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cp /root/redis<span class="literal">-5</span>.<span class="number">0.5</span>/redis.conf /root/redis_cluster/<span class="number">7001</span>/bin</span><br></pre></td></tr></table></figure>
</li>
<li><p>修改配置文件</p>
<p>  1 端口号</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/142002-14345.png" alt="image-20210114142001237"></p>
</li>
</ul>
<p>​       2  打开cluster-enable yes</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/142104-78557.png" alt="image-20210114142104172"></p>
<p>​    3  后台进程 开启  daemonize yes</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/142214-366898.png" alt="image-20210114142214518"></p>
<p>   4   保护模式 关闭</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/133752-642747.png" alt="image-20210114142249346"></p>
<ul>
<li><p>复制7001，创建7002~7006实例，<strong>注意端口修改</strong>。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cp -r &#x2F;root&#x2F;redis_cluster&#x2F;7001&#x2F;* &#x2F;root&#x2F;redis_cluster&#x2F;7002</span><br><span class="line">cp -r &#x2F;root&#x2F;redis_cluster&#x2F;7001&#x2F;* &#x2F;root&#x2F;redis_cluster&#x2F;7003 </span><br><span class="line">cp -r &#x2F;root&#x2F;redis_cluster&#x2F;7001&#x2F;* &#x2F;root&#x2F;redis_cluster&#x2F;7004 </span><br><span class="line">cp -r &#x2F;root&#x2F;redis_cluster&#x2F;7001&#x2F;* &#x2F;root&#x2F;redis_cluster&#x2F;7005 </span><br><span class="line">cp -r &#x2F;root&#x2F;redis_cluster&#x2F;7001&#x2F;* &#x2F;root&#x2F;redis_cluster&#x2F;7006</span><br></pre></td></tr></table></figure>
</li>
<li><p>创建 start.sh 启动所有实例</p>
 <figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd <span class="number">7001</span>/bin</span><br><span class="line">./redis<span class="literal">-server</span> redis.conf</span><br></pre></td></tr></table></figure>

</li>
</ul>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"> cd ..</span><br><span class="line">cd ..</span><br><span class="line">cd <span class="number">7002</span>/bin</span><br><span class="line">./redis<span class="literal">-server</span> redis.conf</span><br><span class="line">cd ..</span><br><span class="line">cd ..</span><br><span class="line"></span><br><span class="line">cd <span class="number">7003</span>/bin</span><br><span class="line">./redis<span class="literal">-server</span> redis.conf</span><br><span class="line">cd ..</span><br><span class="line">cd ..</span><br><span class="line"></span><br><span class="line">cd <span class="number">7004</span>/bin</span><br><span class="line">./redis<span class="literal">-server</span> redis.conf</span><br><span class="line">cd ..</span><br><span class="line">cd ..</span><br><span class="line">cd <span class="number">7005</span>/bin</span><br><span class="line">./redis<span class="literal">-server</span> redis.conf</span><br><span class="line">cd ..</span><br><span class="line">cd ..</span><br><span class="line"></span><br><span class="line">cd <span class="number">7006</span>/bin</span><br><span class="line">./redis<span class="literal">-server</span> redis.conf</span><br><span class="line">cd ..</span><br><span class="line">cd ..</span><br></pre></td></tr></table></figure>

<p>  chmod u+x start.sh (赋写和执行的权限) </p>
<p> ./start.sh(启动RedisCluster)</p>
<ul>
<li>创建Redis集群（创建时Redis里不要有数据）</li>
</ul>
<p>​         进入到任何一个实例下的bin 目录</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd redis_cluster/<span class="number">7001</span>/bin/</span><br></pre></td></tr></table></figure>

<p> 执行 集群创建集群命令</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./redis<span class="literal">-cli</span> -<span class="literal">-cluster</span> create <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7001</span> <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7002</span> <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7003</span> <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7004</span> <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7005</span> <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7006</span> -<span class="literal">-cluster</span><span class="literal">-replicas</span> <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p> 看到如下信息 回复yes</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/143447-961623.png" alt="image-20210114143446447"></p>
<p>  最后看到如下信息说明成功</p>
<p>​            <img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/143522-36593.png" alt="image-20210114143522864"></p>
<ul>
<li>命令客户端连接集群  注意：<strong>-c</strong> 表示是以redis集群方式进行连接</li>
</ul>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./redis<span class="literal">-cli</span> <span class="literal">-h</span> <span class="number">127.0</span>.<span class="number">0.1</span> <span class="literal">-p</span> <span class="number">7001</span> <span class="literal">-c</span></span><br></pre></td></tr></table></figure>

<p>   执行命令测试</p>
   <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">set name 111</span><br></pre></td></tr></table></figure>

<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/143849-230533.png" alt="image-20210114143848490"></p>
<p>查看集群状态</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cluster info</span><br></pre></td></tr></table></figure>


<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/144006-851450.png" alt="image-20210114144003634"></p>
<p>查看集群中的节点</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cluster nodes</span><br></pre></td></tr></table></figure>

<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/144133-335819.png" alt="image-20210114144132655"></p>
<p> 到此为止   redis 集群搭建成功！！！</p>
<p>​                 —————————————————动态扩容——————————————————————</p>
<p>先创建7007 主节点 （无数据） 7008从节点 （无数据）</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">mkdir redis_cluster/<span class="number">7007</span></span><br><span class="line">mkdir redis_cluster/<span class="number">7008</span></span><br><span class="line">make install PREFIX=/root/redis_cluster/<span class="number">7007</span></span><br><span class="line">make install PREFIX=/root/redis_cluster/<span class="number">7008</span></span><br><span class="line"><span class="comment">#拷贝配置文件 并进行端口修改</span></span><br><span class="line">cp /root/redis<span class="literal">-5</span>.<span class="number">0.5</span>/redis.conf /root/redis_cluster/<span class="number">7007</span>/bin</span><br><span class="line">cp /root/redis<span class="literal">-5</span>.<span class="number">0.5</span>/redis.conf /root/redis_cluster/<span class="number">7008</span>/bin</span><br></pre></td></tr></table></figure>

<p>添加7007结点作为新节点,并启动</p>
<p>   后面地址是集群的一个ip地址表示要加入到该集群中</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.&#x2F;redis-cli --cluster add-node 10.9.49.202:7007 10.9.49.202:7001</span><br></pre></td></tr></table></figure>

<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/153905-774723.png" alt="image-20210114153904347"> </p>
<p>​           <strong>添加完主节点需要对主节点进行hash槽分配，这样该主节才可以存储数据。</strong></p>
<p>​           <strong>给刚添加的7007结点分配槽</strong></p>
<ul>
<li><p>​    <strong>第一步：连接上集群（连接集群中任意一个可用结点都行）</strong></p>
  <figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./redis<span class="literal">-cli</span> -<span class="literal">-cluster</span> reshard <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7007</span></span><br></pre></td></tr></table></figure>
</li>
<li><p><strong>第二步：输入要分配的槽数量</strong></p>
<p> How many slots do you want to move (from 1 to 16384)? 3000</p>
</li>
</ul>
<p>​     输入：<strong>3000</strong>，表示要给目标节点分配3000个槽</p>
<ul>
<li><strong>第三步：输入接收槽的结点id</strong></li>
</ul>
<p>​          What is the receiving node ID?</p>
<p>输入：bcbac44a7830a8e23f3bd07cb69a38df04aa1a2c</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">PS：这里准备给7007分配槽，通过cluster nodes查看7007结点id为：</span><br><span class="line">bcbac44a7830a8e23f3bd07cb69a38df04aa1a2c</span><br></pre></td></tr></table></figure>

<ul>
<li><strong>第四步：输入源结点id</strong></li>
</ul>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/154653-638862.png" alt="image-20210114154653083"></p>
<p>  表示从所有节点上 一共分配3000 个节点</p>
<ul>
<li><strong>第五步：输入yes开始移动槽到目标结点id</strong></li>
</ul>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/154848-182152.png" alt="image-20210114154847720"></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/154908-348436.png" alt="image-20210114154908085"></p>
<p>  <strong>添加从节点</strong></p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./redis<span class="literal">-cli</span> -<span class="literal">-cluster</span> <span class="built_in">add-node</span> <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7008</span> <span class="number">10.9</span>.<span class="number">49.202</span>:<span class="number">7007</span> -<span class="literal">-cluster</span><span class="literal">-slave</span> -<span class="literal">-cluster</span><span class="literal">-master</span><span class="literal">-id</span>  bcbac44a7830a8e23f3bd07cb69a38df04aa1a2c</span><br></pre></td></tr></table></figure>



<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/155118-982584.png" alt="image-20210114155117757"></p>
<p> 查看 扩容后结果</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/14/155234-192808.png" alt="image-20210114155233904"></p>
<p>   成功</p>
<h2 id="遇到问题-在客户端执行命名-报"><a href="#遇到问题-在客户端执行命名-报" class="headerlink" title="遇到问题 在客户端执行命名 报"></a>遇到问题 在客户端执行命名 报</h2><ol>
<li><p><strong>error MOVED 原因和解决方案</strong></p>
<p>原因①②③④</p>
</li>
</ol>
<p>这种情况一般是因为启动redis-cli时没有设置集群模式所导致</p>
<p>启动时使用-c参数来启动集群模式，命令如下：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-cli -c -p 7000</span><br></pre></td></tr></table></figure>

<ol start="2">
<li><a href="https://www.cnblogs.com/enjoyjava/p/11361127.html" target="_blank" rel="noopener">(error) CLUSTERDOWN The cluster is down</a></li>
</ol>
<p>​       外部不到redis 集群 所以修改了 nodes.conf  内网地址为 外网地址 导致  报这个错</p>
<p>解决过程   </p>
<p>​    ① 删除所有节点的 dump.rdb 和nodes.conf文件删除  </p>
<p>​     ②   <strong>开放17001-17008</strong>(重要)</p>
<p>​    ③ 节点创建使用外网地址     否则集群无法创建成功</p>
<p>​       ok 成功访问。使用客户端查看信息 </p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/112824-690646.png" alt="image-20210115112823240"></p>
<p>   用Jedis 代码查看   </p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/15/134443-257713.png" alt="image-20210115134442139"></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2021/01/14/redis%20%E9%9B%86%E7%BE%A4%EF%BC%88redis_cluster%EF%BC%89%E6%90%AD%E5%BB%BA/" data-id="cko3snvx80017i8uoconq78nh" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-MongoDB和Neo4j学习笔记" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2021/01/06/MongoDB%E5%92%8CNeo4j%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" class="article-date">
  <time datetime="2021-01-06T02:31:13.013Z" itemprop="datePublished">2021-01-06</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2021/01/06/MongoDB%E5%92%8CNeo4j%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">MongoDB和Neo4j学习笔记</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<p>categories: NoSql<br>—                                                                 MongoDB 和Neo4j  学习笔记</p>
<p>整理 一些常用 命令</p>
<p>查看数据库 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">show dbs;</span><br></pre></td></tr></table></figure>

<p> 切换数据库 如果没有对应的数据库则创建 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">use 数据库名;</span><br></pre></td></tr></table></figure>

<p>创建集合 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.createCollection(&quot;集合名&quot;)</span><br></pre></td></tr></table></figure>

<p>查看集合 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">show tables; </span><br><span class="line">show collections;</span><br></pre></td></tr></table></figure>

<p>删除集合 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.集合名.drop();</span><br></pre></td></tr></table></figure>

<p>删除当前数据库 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.dropDatabase();</span><br></pre></td></tr></table></figure>

<p>插入多条数据</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.集合名.insert([文档,文档])</span><br></pre></td></tr></table></figure>

<p>查询</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.集合名.find(&#123;key1:value1, key2:value2&#125;).pretty()</span><br></pre></td></tr></table></figure>

<p>分页查询</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.集合名.find(&#123;条件&#125;).sort(&#123;排序字段:排序方式&#125;)).skip(跳过的行数).limit(一页显示多少数据)</span><br></pre></td></tr></table></figure>

<p><strong>Neo4j</strong></p>
<p>​       Neo4j是一个开源的 无Shcema的 基于java开发的 图形数据库，它将结构化数据存储在图中而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎。程序数据是在一个面向对象的、灵活的网络结构下，而不是严格、静态的表中,但可以享受到具备完全的事务特性、企业级的数据库的所有好处。</p>
<p><strong>Neo4j</strong> <strong>主要构建块</strong></p>
<ul>
<li><p>节点</p>
</li>
<li><p>属性</p>
</li>
<li><p>关系</p>
</li>
<li><p>标签</p>
</li>
<li><p>数据浏览器</p>
</li>
</ul>
<p><strong>Neo4j CQL</strong></p>
<p>CQL代表Cypher查询语言。 像关系型数据库具有查询语言SQL，Neo4j使用CQL作为查询语言。</p>
<ul>
<li><p>它是Neo4j图形数据库的查询语言。</p>
</li>
<li><p>它是一种声明性模式匹配语言。</p>
</li>
<li><p>它遵循SQL语法。</p>
</li>
<li><p>它的语法是非常简单且人性化、可读的格式。</p>
</li>
</ul>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202101/06/103036-44145.png" alt="image-20210106103034711"></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2021/01/06/MongoDB%E5%92%8CNeo4j%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" data-id="cko3snvwr000di8uo00pxco9g" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-集群环境" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/12/25/%E9%9B%86%E7%BE%A4%E7%8E%AF%E5%A2%83/" class="article-date">
  <time datetime="2020-12-25T08:54:30.448Z" itemprop="datePublished">2020-12-25</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/MySql/">MySql</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/12/25/%E9%9B%86%E7%BE%A4%E7%8E%AF%E5%A2%83/">集群环境</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>​                                                                集群环境</p>
<ul>
<li><p>实现功能  </p>
<p> 主master1负责写，从slave1 slave2负责读</p>
<p> 主master2负责写，从slave3 slave4负责读</p>
</li>
<li><p>代码</p>
<p>* 主要类&amp;方法&amp;参数&amp;返回值及代码行标注注释</p>
<p>* 基于user_id对c_order表进⾏数据分⽚</p>
<p>* 基于master1和master2主从集群实现读写分离</p>
<p>ShowTime</p>
<p>说明  各 ip  如下图</p>
</li>
</ul>
<p>  <img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/25/163907-351786.png" alt="image-20201225163906164"></p>
<p>  接下来 代码请求插入操作</p>
<p>  ​     #  视频演示 </p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2020/12/25/%E9%9B%86%E7%BE%A4%E7%8E%AF%E5%A2%83/" data-id="cko3snvxf001mi8uoa3vue0g1" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-分库分表实战及中间件" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/12/25/%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8%E5%AE%9E%E6%88%98%E5%8F%8A%E4%B8%AD%E9%97%B4%E4%BB%B6/" class="article-date">
  <time datetime="2020-12-25T06:50:34.760Z" itemprop="datePublished">2020-12-25</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/12/25/%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8%E5%AE%9E%E6%88%98%E5%8F%8A%E4%B8%AD%E9%97%B4%E4%BB%B6/">分库分表实战及中间件</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<p>categories: 分库分表<br>—                                                                <strong>分库分表实战及中间件</strong></p>
<p><strong>背景描述</strong></p>
<ul>
<li><p>刚开始我们的系统只用了<strong>单机数据库</strong></p>
</li>
<li><p>随着用户的不断增多，考虑到系统的高可用和越来越多的用户请求，我们开始使用数据库<strong>主从架构</strong></p>
</li>
<li><p>当用户量级和业务进一步提升后，写请求越来越多，这时我们开始使用了<strong>分库分表</strong></p>
</li>
</ul>
<p><strong>遇到的问题</strong></p>
<ul>
<li>用户请求量太大</li>
</ul>
<p>​         单服务器TPS、内存、IO都是有上限的，需要将请求打散分布到多个服务器</p>
<ul>
<li>单库数据量太大</li>
</ul>
<p>​       单个数据库处理能力有限；单库所在服务器的磁盘空间有限；单库上的操作IO有瓶颈</p>
<ul>
<li>单表数据量太大</li>
</ul>
<p>​       查询、插入、更新操作都会变慢，在加字段、加索引、机器迁移都会产生高负载，影响服务</p>
<p><strong>如何解决</strong></p>
<ul>
<li><p>垂直拆分</p>
<p> 垂直分库</p>
</li>
</ul>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/25/165606-796440.png" alt="image-20201225135530458"></p>
<p>​         垂直分表</p>
<p>表中字段太多且包含大字段的时候，在查询时对数据库的IO、内存会受到影响，同时更新数据时，产生的binlog文件会很大，MySQL在主从同步时也会有延迟的风险</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/25/135653-911806.png" alt="image-20201225135651977"></p>
<ul>
<li>水平拆分</li>
</ul>
<p>​      水平分表</p>
<p>​    针对数据量巨大的单张表（比如订单表），按照规则把一张表的数据切分到多张表里面去。但是这些表还是在同一个库中，所以库级别的数据库操作还是有IO瓶颈。</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/25/135826-798413.png" alt="image-20201225135825913"></p>
<p>​    水平分库</p>
<p>将单张表的数据切分到多个服务器上去，每个服务器具有相应的库与表，只是表中数据集合不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力，突破IO、连接数、硬件资源等的瓶颈</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/25/140249-432409.png" alt="image-20201225140248714"></p>
<ul>
<li>水平分库规则</li>
</ul>
<p>不跨库、不跨表，保证同一类的数据都在同一个服务器上面。</p>
<p>数据在切分之前，需要考虑如何高效的进行数据获取，如果每次查询都要跨越多个节点，就需要谨慎使用。</p>
<ul>
<li>水平分表规则</li>
</ul>
<p>​           RANGE</p>
<p>​               时间：按照年、月、日去切分。例如order_2020、order_202005、order_20200501</p>
<p>​               地域：按照省或市去切分。例如order_beijing、order_shanghai、order_chengdu</p>
<p>​               大小：从0到1000000一个表。例如1000001-2000000放一个表，每100万放一个表</p>
<p>​            HASH</p>
<p>​               用户ID取模</p>
<p>业务层改造</p>
<p>​     基于代理层方式：Mycat、Sharding-Proxy、MySQL Proxy</p>
<p>基于应用层方式：Sharding-jdbc</p>
<ul>
<li>分库后面临的问题</li>
</ul>
<p>​              事务问题：一次投递需要插入两条记录，且分布在不同的服务器上，数据需要保障一致性。</p>
<p>​             跨库跨表的join问题:</p>
<p>​               全局表（字典表）：基础数据/配置数据，所有库都拷贝一份</p>
<p>​              字段冗余：可以使用字段冗余就不用join查询了</p>
<p>​              系统层组装：可以在业务层分别查询出来，然后组装起来，逻辑较复杂额外的数据管理负担和数据运算压力：数 据库扩容、维护成本变高.</p>
<p><strong>ShardingSphere</strong></p>
<p>Apache ShardingSphere是一款开源的分布式数据库中间件组成的生态圈。它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar（规划中）这3款相互独立的产品组成。 他们均提供标准化的数据</p>
<p> 分片、分布式事务和数据库治理功能，可适用于如Java同构、异构语言、容器、云原生等各种多样化的</p>
<p>应用场景。</p>
<p>Sharding-JDBC：被定位为轻量级Java框架，在Java的JDBC层提供的额外服务，以jar包形式使用。</p>
<p>Sharding-Proxy：被定位为透明化的数据库代理端，提供封装了数据库二进制协议的服务端版本，用于完成对异构语言的支持。</p>
<p>Sharding-Sidecar：被定位为Kubernetes或Mesos的云原生数据库代理，以DaemonSet的形式代理所有对数据库的访问。</p>
<p>​    </p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2020/12/25/%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8%E5%AE%9E%E6%88%98%E5%8F%8A%E4%B8%AD%E9%97%B4%E4%BB%B6/" data-id="cko3snvxc001hi8uo6dvf6wj2" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-linux 作业题" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/12/18/linux%20%E4%BD%9C%E4%B8%9A%E9%A2%98/" class="article-date">
  <time datetime="2020-12-18T08:49:33.206Z" itemprop="datePublished">2020-12-18</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/12/18/linux%20%E4%BD%9C%E4%B8%9A%E9%A2%98/">linux 作业题</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="categories-MySql数据库"><a href="#categories-MySql数据库" class="headerlink" title="categories: MySql数据库"></a>categories: MySql数据库</h2><p>linux 作业题</p>
<p><strong>搭建一个MySQL高可用架构集群环境（4台主机，1主、2从、1 MHA）</strong></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/18/165713-354069.png" alt="image-20201218165712462"></p>
<p> 如上图 CoderCheng 为主库    UCloud  和 UCloud1年  为两个从库</p>
<p>以dept 为库为演示    </p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/18/170115-644437.png" alt="image-20201218170115160"></p>
<p>  从库 和主库 目前只要这几条数据  现在 我在主库添加一条数据</p>
<p>id为4    name的5数据</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/18/171449-724149.png" alt="image-20201218170611409"></p>
<p>刷新从库 可以看到 数据已经同步过来了 </p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/18/171436-319152.png" alt="image-20201218170740855"></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/18/170801-195533.png" alt="image-20201218170800466"></p>
<p>说明 主从同步成功</p>
<p> 以下命名在主库用到命令</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/18/170922-801950.png" alt="image-20201218170921953"></p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/18/170947-620462.png" alt="image-20201218170947061"></p>
<p>以下命令从库 用到</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/18/171031-566571.png" alt="image-20201218171031275"></p>
<p>说明满足主从 半同步复制。</p>
<p> 接下来 测试mha功能  </p>
<p>备注  </p>
<p>39.106.214.114  master</p>
<p>106.75.20.63     slave</p>
<p>117.50.7.7     slave</p>
<p>106.75.31.205   manager </p>
<ul>
<li><p>首先4台机器进行ssh免密登录  </p>
<p>配置完成后使用命令测试</p>
</li>
</ul>
  <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">masterha_check_ssh -conf=/etc/mha_master/mha.cnf</span><br></pre></td></tr></table></figure>

<p>  出现下图所示代表ssh 免密成功</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/19/090608-553293.png" alt="image-20201219084600607"></p>
<ul>
<li><p>进行主从复制测试（出现下图表示成功）</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">masterha_check_repl <span class="literal">-conf</span>=/etc/mha_master/mha.cnf &gt; /etc/mha_master/manager.log &amp;</span><br></pre></td></tr></table></figure>

<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/19/084940-376922.png" alt="image-20201219084939148"></p>
</li>
<li><p>接下来 启动 manager管理节点查看主从切换日志</p>
</li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">masterha_manager --conf=/etc/mha_master/mha.cnf &lt; /etc/mha_master/manager.log &amp;</span><br></pre></td></tr></table></figure>

<p>​       接下来手动关闭  39.106.214.114  模拟故障  master mysql  查看 manager日志</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/19/091136-580829.png" alt="image-20201219091135589"></p>
<p>  出现  这个 成功 说明   已经  mha 切换可以成功</p>
<p>   下面在新的master添加一条数据 测试 是否成成功</p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/19/091935-930142.png" alt="image-20201219091935067"></p>
<p>​    开始在新的master（Ucloud）添加一条 id 888  name 666的数据  刷新 slave （UCloud1年）库查看数据  </p>
<p><img src="https://gitee.com/adc123321/blog_img/raw/master/image/202012/19/092100-605003.png" alt="image-20201219092058063"></p>
<p><strong>测试成功！！！</strong></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2020/12/18/linux%20%E4%BD%9C%E4%B8%9A%E9%A2%98/" data-id="cko3snvx30012i8uofgekctt9" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  


  <nav id="page-nav">
    
    <a class="extend prev" rel="prev" href="/page/2/">&amp;laquo; 上一页</a><a class="page-number" href="/">1</a><a class="page-number" href="/page/2/">2</a><span class="page-number current">3</span><a class="page-number" href="/page/4/">4</a><a class="page-number" href="/page/5/">5</a><a class="page-number" href="/page/6/">6</a><a class="extend next" rel="next" href="/page/4/">下一页 &amp;raquo;</a>
  </nav>

</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">分类</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Java/">Java</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/MySql/">MySql</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Netty/">Netty</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/SpringBoot/">SpringBoot</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/SpringCloud/">SpringCloud</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/SpringMVC/">SpringMVC</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Tomcat/">Tomcat</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Zookeeper/">Zookeeper</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E4%BD%9C%E4%B8%9A/">作业</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%88%86%E5%B8%83%E5%BC%8F%E8%B0%83%E5%BA%A6/">分布式调度</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E6%A1%86%E6%9E%B6/">框架</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E7%9F%A5%E8%AF%86/">知识</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a></li></ul>
    </div>
  </div>


  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2024/08/">八月 2024</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/09/">九月 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/08/">八月 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/04/">四月 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/02/">二月 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/11/">十一月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/06/">六月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/05/">五月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/04/">四月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/03/">三月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/02/">二月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/01/">一月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/12/">十二月 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/11/">十一月 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/10/">十月 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/09/">九月 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/08/">八月 2020</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2024/08/28/CentOS%E5%86%85%E5%AD%98cpu%E6%8E%92%E6%9F%A5/">CentOS内存cpu排查</a>
          </li>
        
          <li>
            <a href="/2022/09/22/Linux%20%E6%9F%A5%E7%9C%8B%E6%97%A5%E5%BF%97%E5%91%BD%E4%BB%A4/">Linux 查看日志命令</a>
          </li>
        
          <li>
            <a href="/2022/08/30/dubbo%20%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/">dubbo 常见问题</a>
          </li>
        
          <li>
            <a href="/2022/04/26/1%20%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/">1 源码笔记</a>
          </li>
        
          <li>
            <a href="/2022/02/24/jvisualVM%20%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/">jvisualVM 使用笔记</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2024 CoderCheng<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//code.jquery.com/jquery-2.0.3.min.js"></script>


  
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">

  
<script src="/fancybox/jquery.fancybox.pack.js"></script>




<script src="/js/script.js"></script>




  </div>
</body>
</html>